use std::thread;
use std::time::Duration;

use std::sync::{ Mutex, Arc };
use std::rc::Rc;

use std::sync::mpsc;

fn main() {
    // threads();
    // channel();
    // channel_sto1();
    mutex();
}

fn threads(){
    let v = vec![1,2,3,4,5];

    let handle = thread::spawn(move || {
        for index in v.iter() {
            println!("This is {}!",index);
            thread::sleep(Duration::from_secs(1));
        }
    });

    // v.drop(); 报错

    for index in 1..5 {
        println!("This is {}!",index);
        thread::sleep(Duration::from_secs(1));
    }

    handle.join().unwrap();
    println!("Hello, world!");
}

// 单一 生产者 消费者 模型
fn channel(){
    let (tx,rx) = mpsc::channel();

    thread::spawn(move || {
        let vars = vec![
            String::from("hi"),
            String::from("hello"),
            String::from("world!"),
            String::from("世界"),
        ];

        for var in vars {
            tx.send(var).unwrap();
            // println!("{}",var);
            thread::sleep(Duration::from_secs(1));
        }
    });

    for msg in rx {
        println!("{}",msg);
    }
}

// 多生产者 一消费者 模型
fn channel_sto1(){
    let (tx,rx) = mpsc::channel();

    // 生产者通道被闭包获取所有权，所以不同的线程必须使用不同的变量
    let tx1 = tx.clone();
    // let tx1 = mpsc::Sender::clone(&tx);

    thread::spawn(move || {
        let vars = vec![
            String::from("hi"),
            String::from("hello"),
            String::from("world!"),
            String::from("世界"),
        ];

        for var in vars {
            tx.send(var).unwrap();
            // println!("{}",var);
            thread::sleep(Duration::from_secs(1));
        }
    });

    thread::spawn(move || {
        let vars = vec![
            String::from("hi"),
            String::from("hello"),
            String::from("world!"),
            String::from("世界"),
        ];

        for var in vars {
            tx1.send(var).unwrap();
            // println!("{}",var);
            thread::sleep(Duration::from_secs(1));
        }
    });

    for msg in rx {
        println!("{}",msg);
    }
}

fn mutex(){
    let mutex = Arc::new(Mutex::new(5));
    let mut handles = vec![];

    for _ in 1..10 {
        let an = Arc::clone(&mutex);
        let handle = thread::spawn(move || {
            let mut num = an.lock().unwrap();
            *num += 1;
        });

        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("{}", *mutex.lock().unwrap())
}
